package org.nobject.common.code.model.java;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class InterfaceModel {

	/**
	 * Package name
	 */
	private String interfacePackage = null;

	/**
	 * Interface name
	 */
	private String interfaceName = "";

	/**
	 * Interface comment
	 */
	private String interfaceComment = null;

	/**
	 * Interface comment author
	 */
	private String interfaceCommentAuthor = null;

	/**
	 * Interface comment version
	 */
	private String interfaceCommentVersion = null;

	/**
	 * interface comment header
	 */
	private String interfaceCommentHeader = null;

	/**
	 * Method map
	 */
	private Map<String, MethodModel> methods = new LinkedHashMap<String, MethodModel>();

	/**
	 * Variabe map
	 */
	private Map<String, VariableModel> variables = new LinkedHashMap<String, VariableModel>();
	
	/**
	 * imports
	 */
	private List imports=new LinkedList();
	
	/**
	 * Constructor
	 */
	public InterfaceModel() {

	}

	/**
	 * Constructor
	 * 
	 * @param interfaceName
	 */
	public InterfaceModel(String interfaceName) {
		this.interfaceName = interfaceName;
	}

	/**
	 * Constructor
	 * 
	 * @param interfacePackage
	 * @param interfaceName
	 */
	public InterfaceModel(String interfaceName, String interfacePackage) {
		this.interfacePackage = interfacePackage;
		this.interfaceName = interfaceName;
	}

	/**
	 * Add method
	 * 
	 * @param method
	 */
	public void addMethod(MethodModel method) {
		method.setMethodInterface(true);
		List params = method.getParams();
		String key = "";
		for (Iterator iterator = params.iterator(); iterator.hasNext();) {
			ParamModel param = (ParamModel) iterator.next();
			key += (param.getParamType() + " " + param.getParamName());
			if (iterator.hasNext()) {
				key += ",";
			}
		}
		this.methods.put(method.getMethodName() + "(" + (key.equals("") ? "" : key) + ")", method);
	}

	/**
	 * Add variable
	 * 
	 * @param variable
	 */
	public void addVariable(VariableModel variable) {
		variables.put(variable.getVariableName(), variable);
	}
	
	/**
	 * addImport
	 * @param classfullName
	 */
	public void addImport(String classfullName){
		this.imports.add(classfullName);
	}
	
	/**
	 * Get interface package
	 * 
	 * @return
	 */
	public String getInterfacePackage() {
		return interfacePackage;
	}

	/**
	 * Set Interface Package
	 * 
	 * @param interfacePackage
	 */
	public void setInterfacePackage(String interfacePackage) {
		this.interfacePackage = interfacePackage;
	}

	/**
	 * Set Interface Name
	 * 
	 * @param interfaceName
	 */
	public void setInterfaceName(String interfaceName) {
		this.interfaceName = interfaceName;
	}

	/**
	 * Get Interface Comment
	 * 
	 * @return
	 */
	public String getInterfaceComment() {
		return interfaceComment;
	}

	/**
	 * Set Interface Comment
	 * 
	 * @param interfaceComment
	 */
	public void setInterfaceComment(String interfaceComment) {
		this.interfaceComment = interfaceComment;
	}

	/**
	 * Get Interface Name
	 * 
	 * @return
	 */
	public String getInterfaceName() {
		return interfaceName;
	}

	/**
	 * Get Interface Comment Author
	 * 
	 * @return
	 */
	public String getInterfaceCommentAuthor() {
		return interfaceCommentAuthor;
	}

	/**
	 * Set Interface Comment Author
	 * 
	 * @param interfaceCommentAuthor
	 */
	public void setInterfaceCommentAuthor(String interfaceCommentAuthor) {
		this.interfaceCommentAuthor = interfaceCommentAuthor;
	}

	/**
	 * Get Interface Comment Version
	 * 
	 * @return
	 */
	public String getInterfaceCommentVersion() {
		return interfaceCommentVersion;
	}

	/**
	 * Set Interface Comment Version
	 * 
	 * @param interfaceCommentVersion
	 */
	public void setInterfaceCommentVersion(String interfaceCommentVersion) {
		this.interfaceCommentVersion = interfaceCommentVersion;
	}

	/**
	 * Get Interface Comment Header
	 * 
	 * @return
	 */
	public String getInterfaceCommentHeader() {
		return interfaceCommentHeader;
	}

	/**
	 * Set Interface Comment Header
	 * 
	 * @param interfaceCommentHeader
	 */
	public void setInterfaceCommentHeader(String interfaceCommentHeader) {
		this.interfaceCommentHeader = interfaceCommentHeader;
	}

	/**
	 * Check
	 * 
	 * @return
	 */
	private boolean check() {
		if (this.interfaceName != null && !this.interfaceName.equals("")) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Generate Interface String
	 * 
	 * @return
	 */
	public String generateInterfaceString() {
		if (!check()) {
			System.err.println("接口名不能为空!");
			return null;
		}
		StringBuffer sb = new StringBuffer();

		if (this.interfaceCommentHeader != null && !this.interfaceCommentHeader.equals("")) {
			sb.append("/*\n");
			sb.append(" * @(#) " + this.interfaceName + ".java" + "\n");
			sb.append(" * " + interfaceCommentHeader + "\n");
			sb.append(" */\n\n");
		}

		if (this.interfacePackage != null) {
			sb.append("package " + this.interfacePackage + ";\n");
		}
		
		for (Iterator iterator = this.imports.iterator(); iterator.hasNext();) {
			String imp = (String) iterator.next();
			sb.append("import "+imp+";");
			sb.append("\n");
		}
		
		sb.append("\n/**\n");
		sb.append(" * " + ((this.interfaceComment != null) ? this.interfaceComment : this.interfaceName) + "\n");
		if (this.interfaceCommentAuthor != null)
			sb.append(" * @author " + this.interfaceCommentAuthor + "\n");
		if (this.interfaceCommentVersion != null)
			sb.append(" * @version " + this.interfaceCommentVersion + "\n");
		sb.append(" */\n");

		sb.append("public interface " + this.interfaceName);
		sb.append("{\n");

		for (Iterator iterator = variables.keySet().iterator(); iterator.hasNext();) {
			String key = (String) iterator.next();
			VariableModel variable = (VariableModel) variables.get(key);
			variable.setVariableStatic(true);
			sb.append("\n");
			sb.append(variable.generateVariableString());
		}

		for (Iterator iterator = methods.keySet().iterator(); iterator.hasNext();) {
			String key = (String) iterator.next();
			MethodModel method = (MethodModel) methods.get(key);
			sb.append("\n");
			sb.append(method.generateMethodString());
		}

		sb.append("\n");

		sb.append("\n");
		sb.append("}");
		return sb.toString();
	}

}
